import tool from '@/tools/utils'
const isIphone = tool.testMobileType()

const win = window.top

// 函数形参伪数组转为数组
function argsToArray (args, start) {
  start = start || 0
  return Array.prototype.slice.call(args, start)
}

// ios新版调用方式
const invokeIos = function () {
  var k = arguments[0];
  if (win.webkit) {
    if (
      win.webkit.messageHandlers
      && win.webkit.messageHandlers[k]
    ) {
      win.webkit.messageHandlers[k].postMessage(
        arguments.length === 1 ? '' : argsToArray(arguments, 1)
      );
      return true;
    }
  }

  return false;
}

/**
   * @description 调用原生方法，安卓原生接口，同时兼容旧版ios接口调用方式
   * @param {string} k 原生方法名
   * @returns
   */
const invokeNative = function (k) {
  const args = argsToArray(arguments, 1);
  if (isIphone == 'ios') {
    return invokeIos.apply(this, [k].concat(args));
  }

  if (win.NativeAPI && win.NativeAPI[k]) {
    win.NativeAPI[k].apply(win.NativeAPI, args);
    return true;
  }
  return false;
}

// 无回调原生方法
var noCallbackAPI = [
  // 关闭定位
  'closePostLocation'
]

// 有回调原生方法
const asyncCallbackAPI = [
  'startPostLocation',
  'getLocation',
  // 调起原生拍照和相册
  'getPicture',
  // 获取上传视频地址
  'takeVideo',
  // 设置视频最大时间
  'setMaxVideoTime',
  // 设置JPUSH别名
  'setJPushAlias',
];

const native = {
  // 是否是app环境
  is: function () {
    if( win.webkit || win.NativeAPI) {
      return true
    }
    return false
    // return (win.webkit && win.webkit.messageHandlers && win.webkit.messageHandlers.openInNewWindow) || win.NativeAPI
  }
}

for (let index = 0; index < noCallbackAPI.length; index++) {
  var k = noCallbackAPI[index];
  native[k] = (function(fName) {
    return function() {
      return invokeNative.apply(this, [fName].concat(argsToArray(arguments, 0)));
    }
  })(k)
}

for (let index = 0; index < asyncCallbackAPI.length; index++) {
  const k = asyncCallbackAPI[index]
  native[k] = (function (fName) {
    return function () {
      const result = invokeNative.apply(this, [fName].concat(argsToArray(arguments, 0)))
      if (result) {
        return new Promise(resolve => {
          const callbackName = fName + 'Callback'

          win[callbackName] = function () {
            // 如果回调参数只有1个，则直接返回这个参数
            resolve(arguments.length === 1 ? arguments[0] : argsToArray(arguments))
            delete win[callbackName]
          }
        })
      } else {
        return Promise.reject(new Error('无此原生方法'))
      }
    }
  })(k)
}

export default native